package cc.comac.mom.datahandlers.entity;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cc.comac.mom.bean.EquipRegularCheckPlan;
import cc.comac.mom.bean.EquipRegularCheckPlanBean;
import cc.comac.mom.bean.EquipRegularCheckWorkOrder;
import cc.comac.mom.bean.ResultDev;
import cc.comac.mom.dao.entity.EquipRegularCheckPlanDao;
import cc.comac.mom.dao.entity.EquipReqularCheckDao;
import cc.comac.mom.entity.EquipRegularCheckPlanEntity;
import cc.comac.mom.entity.EquipRegularCheckWorkOrderEntity;
import cc.comac.mom.entity.EquipReqularCheckEntity;
import cc.comac.mom.redis.IdFactory;
import cc.comac.mom.util.BaseEntityDataUtil;
import cc.comac.mom.util.MomConstants;
import cc.comac.mom.util.ResultBean;
import cc.comac.mom.util.TimeUtil;

@Component
@Transactional
public class EquipRegularCheckPlanDataHandler extends ServiceImpl<EquipRegularCheckPlanDao, EquipRegularCheckPlanEntity>{
	@Autowired
	private EquipRegularCheckPlanDao equipRegularCheckPlanDao;
	
	@Resource
	private IdFactory idFactory;
	
	@Autowired
	private BaseEntityDataUtil baseEntityDataUtil;
	
	@Autowired
	private EquipReqularCheckDao equipReqularCheckDao;
	
	@Autowired
	private EquipRegularCheckWorkOrderDataHandler equipRegularCheckWorkOrderDataHandler;
	
	public ResultBean insert(EquipRegularCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
        ResultBean resultBean2 = this.checkData(obj);
        if(!resultBean2.success) {
        	return resultBean2;
        }
		EquipRegularCheckPlanEntity innerData = obj.getInnerData();
		innerData.setPlanNumber(idFactory.generateEquipRegularCheckPlanNo());
		innerData.setIsAlendar(0);//未到期
		innerData.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_NOISSUE);
		baseEntityDataUtil.setBaseEntityData(innerData);
		int insert = equipRegularCheckPlanDao.insert(innerData);
		if(insert<1) {
			throw new RuntimeException("保存定检计划失败");
		}
		return resultBean;
	}
	//批量新增定检计划
	public ResultBean insertBatch(List<EquipRegularCheckPlan> list) {
		ResultBean resultBean = new ResultBean(true);
		if(list == null || list.size()<1) {
			throw new RuntimeException("数据为空");
		}
		ArrayList<EquipRegularCheckPlanEntity> listEntity = new ArrayList<EquipRegularCheckPlanEntity>();
		for(EquipRegularCheckPlan item:list){
			ResultBean checkData = this.checkData(item);
			if(!checkData.success) {
				return checkData;
			}
		}
		for(EquipRegularCheckPlan item2:list) {
			EquipRegularCheckPlanEntity innerData = item2.getInnerData();
			innerData.setPlanNumber(idFactory.generateEquipRegularCheckPlanNo());
			innerData.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_NOISSUE);
			baseEntityDataUtil.setBaseEntityData(innerData);
			listEntity.add(innerData);
		}
		boolean saveBatch = this.saveBatch(listEntity);
		if(!saveBatch) {
			throw new RuntimeException("保存定检计划失败");
		}
		return resultBean;
	}
	//修改
	public ResultBean update(EquipRegularCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
		ResultBean checkData = this.checkData(obj);
		if(!checkData.success) {
			return checkData;
		}
		EquipRegularCheckPlanEntity innerData = obj.getInnerData();
		if(innerData.getStatus() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {
			throw new RuntimeException("计划已发布，不允许修改");
		}
		baseEntityDataUtil.updateBaseEntityData(innerData);
		int updateById = equipRegularCheckPlanDao.updateById(innerData);
		if(updateById<1) {
			throw new RuntimeException("修改定检计划失败");
		}
		return resultBean;
	}
	
	//校验数据
	public ResultBean checkData(EquipRegularCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
		if(obj == null || obj.getInnerData() == null) {
			throw new RuntimeException("数据为空");
		}
		if(obj.getInnerData().getDevCategoryId() == 0) {
			throw new RuntimeException("设备类型为空");
		}
		if(obj.getInnerData().getDevId() == 0) {
			throw new RuntimeException("设备编号为空");
		}
		if(obj.getInnerData().getCheckBenchmarkId() == 0) {
			throw new RuntimeException("点检信息为空");
		}
		if(StringUtils.isEmpty(obj.getInnerData().getCycle()) || obj.getInnerData().getCycleValue() <=0) {
			throw new RuntimeException("循环周期为空");
		}
		if(obj.getInnerData().getFirstPlanStartDate() == null) {
			throw new RuntimeException("首次开始日期为空");
		}
		EquipReqularCheckEntity reqularCheckEntity = equipReqularCheckDao.selectById(obj.getInnerData().getCheckBenchmarkId());
		if(reqularCheckEntity == null) {
			throw new RuntimeException("定检信息不存在");
		}
		if(StringUtils.isEmpty(reqularCheckEntity.getFrequentType()) || reqularCheckEntity.getFrequentValue() <=0) {
			throw new RuntimeException("定检频率为空");
		}
		//校验定检频率和周期是否符合
		int frequent = this.getCycleDataToHouse(reqularCheckEntity.getFrequentType(), reqularCheckEntity.getFrequentValue());
		int cycle = this.getCycleDataToHouse(obj.getInnerData().getCycle(), obj.getInnerData().getCycleValue());
		if(frequent>cycle) {
			throw new RuntimeException("循环周期必须大于定检频率");
		}
		LocalDateTime cycleDataToDateTime = this.getCycleDataToDateTime(obj.getInnerData().getCycle(), obj.getInnerData().getCycleValue(),TimeUtil.fomatDateToLocalDateTime(obj.getInnerData().getFirstPlanStartDate()));
		LocalDateTime now = LocalDateTime.now();
		if(now.isAfter(cycleDataToDateTime)) {
			throw new RuntimeException("过期配置，请重新配置");
		}
		return resultBean;
	}
	//批量删除
	public ResultBean deleteBatch(List<EquipRegularCheckPlan>list) {
		ResultBean resultBean = new ResultBean(true);
		if(list == null || list.size()<1) {
			throw new RuntimeException("数据为空");
		}
		ArrayList<Long> listIds = new ArrayList<Long>();
		for(EquipRegularCheckPlan item :list ) {
			EquipRegularCheckPlanEntity innerData = item.getInnerData();
			if(innerData == null) {
				throw new RuntimeException("数据为空");
			}
			listIds.add(innerData.getId());
		}
		List<EquipRegularCheckPlanEntity> selectBatchIds = equipRegularCheckPlanDao.selectBatchIds(listIds);
		if(selectBatchIds == null || selectBatchIds.size()<1) {
			throw new RuntimeException("数据为空");
		}
		for(EquipRegularCheckPlanEntity item :selectBatchIds) {
			//已发布的不允许删除
			if(item.getStatus()==MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {
				throw new RuntimeException("工单号:"+item.getPlanNumber()+" 已发布，不允许删除");
			}
			baseEntityDataUtil.deleteBaseEntityData(item);
		}
		boolean updateBatchById = this.updateBatchById(selectBatchIds);
		if(!updateBatchById) {
			throw new RuntimeException("批量删除定检计划失败");
		}
		return resultBean;
	}
	//发布
	public ResultBean planIssue(List<Long> list) {
		ResultBean resultBean = new ResultBean(true);
		if(list == null || list.size()<1) {
			throw new RuntimeException("数据为空");
		}
		List<EquipRegularCheckPlanEntity> selectBatchIds = equipRegularCheckPlanDao.selectBatchIds(list);
		if(selectBatchIds == null || selectBatchIds.size()<1){
			throw new RuntimeException("数据为空");
		}
		ArrayList<EquipRegularCheckWorkOrder> listEquipRegularCheckWorkOrder = new  ArrayList<EquipRegularCheckWorkOrder>();
		for(EquipRegularCheckPlanEntity item :selectBatchIds) {
			//已发布，不允许再次发布
			if(item.getStatus() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {	
				throw new RuntimeException("该定检计划已经发布，不允许操作");
			}
			EquipReqularCheckEntity reqularCheckEntity = equipReqularCheckDao.selectById(item.getCheckBenchmarkId());
			if(reqularCheckEntity == null) {
				throw new RuntimeException("定检信息不存在");
			}
			if(StringUtils.isEmpty(reqularCheckEntity.getFrequentType()) || reqularCheckEntity.getFrequentValue() <=0) {
				throw new RuntimeException("定检频率为空");
			}
			 LocalDateTime planStartData = null;
		//	 LocalDateTime planEndData = null;
			 LocalDateTime nowData = LocalDateTime.now();
			//校验定检频率和周期是否符合
			int frequent = this.getCycleDataToHouse(reqularCheckEntity.getFrequentType(), reqularCheckEntity.getFrequentValue());
	//		int cycle = this.getCycleDataToHouse(item.getCycle(), item.getCycleValue());
			int executionHours = this.getCycleDataToHouse(item.getExecutionTime(), item.getExecutionTimeValue());
			//首次开始日期
			LocalDateTime firstPlanStartData = TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate());
			//周期结束日期
			LocalDateTime cycleDataToDateTime = this.getCycleDataToDateTime(item.getCycle(), item.getCycleValue(),firstPlanStartData);
			
			// planStartData = firstPlanStartData.plusHours(frequent);
			
			//判断发布当天是否要生成工单
			   //发布日期在首个开始日期之前,且 不考虑工作日历
			if(nowData.isBefore(firstPlanStartData) && item.getIsAlendar() == 0) {
				item.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED);
				item.setPlanStartDate(item.getFirstPlanStartDate());
				item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(firstPlanStartData.plusHours(executionHours)));
				baseEntityDataUtil.updateBaseEntityData(item);
				//发布日期在首次日期之前,当天生成工单,开始日期为首次日期
				EquipRegularCheckWorkOrder equipRegularCheckWorkOrder = new EquipRegularCheckWorkOrder();
				EquipRegularCheckWorkOrderEntity equipRegularCheckWorkOrderEntity = new EquipRegularCheckWorkOrderEntity();
				equipRegularCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipRegularCheckPlanOrderNo());
				equipRegularCheckWorkOrderEntity.setEquipCheckPlanId(item.getId());
				equipRegularCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
				equipRegularCheckWorkOrderEntity.setCheckBenchmarkId(item.getCheckBenchmarkId());
				equipRegularCheckWorkOrderEntity.setDevId(item.getDevId());
				equipRegularCheckWorkOrderEntity.setDevCategoryId(item.getDevCategoryId());
				equipRegularCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
				equipRegularCheckWorkOrderEntity.setFirstPlanStartDate(item.getFirstPlanStartDate());
				equipRegularCheckWorkOrderEntity.setExecutionTime(item.getExecutionTime());
				equipRegularCheckWorkOrderEntity.setExecutionTimeValue(item.getExecutionTimeValue());
				equipRegularCheckWorkOrderEntity.setCycle(item.getCycle());
				equipRegularCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
				equipRegularCheckWorkOrderEntity.setPlanStartDate(item.getFirstPlanStartDate());
				equipRegularCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()).plusHours(executionHours)));
				equipRegularCheckWorkOrderEntity.setLocation(item.getLocation());
				equipRegularCheckWorkOrderEntity.setActualTeam(item.getActualTeam());
				equipRegularCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
				equipRegularCheckWorkOrder.setInnerData(equipRegularCheckWorkOrderEntity);
				listEquipRegularCheckWorkOrder.add(equipRegularCheckWorkOrder);
				continue;
			}else if(nowData.isBefore(firstPlanStartData) && item.getIsAlendar() != 0) {
				//考虑工作日历
				throw new RuntimeException("计划单号:"+item.getPlanNumber()+"需要考虑工作日历");
			}else if(nowData.isAfter(firstPlanStartData) && item.getIsAlendar() == 0) {
				//发布日期在首个日期之后,生成下一个工单,且不考虑工作日历
				//
				for(int i =1 ;i<100000;i++) {
					planStartData = firstPlanStartData.plusHours(frequent*i);
					if(nowData.isBefore(planStartData)) {
						break;
					}else {
						continue;
					}
				}
				if(nowData.isBefore(planStartData)) {
					//此时planStartData就是下一个要生成的工单的开始日期
					if(planStartData.isAfter(cycleDataToDateTime)) {
						//已到期
						throw new RuntimeException("计划单号:"+item.getPlanNumber()+"已过期，不能下发");
					}else {
						item.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED);
						item.setPlanStartDate(TimeUtil.fomatLocalDateTimeToDate(planStartData));
						item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(planStartData.plusHours(executionHours)));
						baseEntityDataUtil.updateBaseEntityData(item);
						//发布日期在首次日期之前,当天生成工单,开始日期为首次日期
						EquipRegularCheckWorkOrder equipRegularCheckWorkOrder = new EquipRegularCheckWorkOrder();
						EquipRegularCheckWorkOrderEntity equipRegularCheckWorkOrderEntity = new EquipRegularCheckWorkOrderEntity();
						equipRegularCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipRegularCheckPlanOrderNo());
						equipRegularCheckWorkOrderEntity.setEquipCheckPlanId(item.getId());
						equipRegularCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
						equipRegularCheckWorkOrderEntity.setCheckBenchmarkId(item.getCheckBenchmarkId());
						equipRegularCheckWorkOrderEntity.setDevId(item.getDevId());
						equipRegularCheckWorkOrderEntity.setDevCategoryId(item.getDevCategoryId());
						equipRegularCheckWorkOrderEntity.setCycle(item.getCycle());
						equipRegularCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
						equipRegularCheckWorkOrderEntity.setPlanStartDate(TimeUtil.fomatLocalDateTimeToDate(planStartData));
						equipRegularCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(planStartData.plusHours(executionHours)));
						equipRegularCheckWorkOrderEntity.setLocation(item.getLocation());
						equipRegularCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
						equipRegularCheckWorkOrderEntity.setFirstPlanStartDate(item.getFirstPlanStartDate());
						equipRegularCheckWorkOrderEntity.setExecutionTime(item.getExecutionTime());
						equipRegularCheckWorkOrderEntity.setExecutionTimeValue(item.getExecutionTimeValue());
						equipRegularCheckWorkOrderEntity.setActualTeam(item.getActualTeam());
						equipRegularCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
						equipRegularCheckWorkOrder.setInnerData(equipRegularCheckWorkOrderEntity);
						listEquipRegularCheckWorkOrder.add(equipRegularCheckWorkOrder);
						continue;
					}
				}else {
					//已过期
					throw new RuntimeException("计划单号:"+item.getPlanNumber()+"已过期，不能下发");
				}
			}else if(nowData.isAfter(firstPlanStartData) && item.getIsAlendar() != 0) {
				//发布日期在首个日期之后,生成下一个工单,且考虑工作日历
				throw new RuntimeException("计划单号:"+item.getPlanNumber()+"需要考虑工作日历");
			}

		}
		//执行批量下发
		boolean updateBatchById = this.updateBatchById(selectBatchIds);
		if(!updateBatchById) {
			throw new RuntimeException("计划下发失败！");
		}
		//执行批量生成工单
		ResultBean insertBatch = equipRegularCheckWorkOrderDataHandler.insertBatch(listEquipRegularCheckWorkOrder);
		if(!insertBatch.success) {
			throw new RuntimeException(insertBatch.getMessage());
		}
		return resultBean;
	}
	//生失效
	public ResultBean disableEquipReqularCheckByIds(List<Long> list) {
		ResultBean resultBean = new ResultBean(true);
		if(list == null || list.size()<1) {
			throw new RuntimeException("数据为空");
		}
		List<EquipRegularCheckPlanEntity> selectBatchIds = equipRegularCheckPlanDao.selectBatchIds(list);
		if(selectBatchIds == null || selectBatchIds.size()<1){
			throw new RuntimeException("数据为空");	
		}
		for(EquipRegularCheckPlanEntity item :selectBatchIds) {
			//已发布，不允许生失效
			if(item.getStatus() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {
				throw new RuntimeException("该定检计划已经发布，不允许操作");
			}
			if(item.getEnable() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ENABLE) {
				item.setEnable(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_DISABLED);
				baseEntityDataUtil.updateBaseEntityData(item);
			}else {
				item.setEnable(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ENABLE);
				baseEntityDataUtil.updateBaseEntityData(item);
			}
		}
		boolean updateBatchById = this.updateBatchById(selectBatchIds);
		if(!updateBatchById) {
			throw new RuntimeException("批量生/失效操作 失败");
		}
		return resultBean;
	}
	
	//查询
	public ResultDev selectByFields(EquipRegularCheckPlanBean obj) {
		ResultDev resultDev = new ResultDev();
		if (obj.getPageSize() == 0) {
			obj.setPageSize(10);
		}
		obj.setPageNum((obj.getPageNum()-1)*obj.getPageSize());
		List<EquipRegularCheckPlanBean> listEquipRegularCheckPlanBean = equipRegularCheckPlanDao.selectByFields(obj);
		long countByFields = equipRegularCheckPlanDao.selectCountByFields(obj);
		
		// 将查询总数除以每页数量后向上取整获取总页数
		double pageCount = Math.ceil((double)countByFields / obj.getPageSize());
		resultDev.setEntityList(listEquipRegularCheckPlanBean);
		resultDev.setPageCount((int)pageCount);
		resultDev.setTotalQuantity((int)countByFields);
		return resultDev;
	}
	
	// 通过计划首次开始时间和循环周期算出结束时间
	public LocalDateTime getCycleDataToDateTime(String unit,int cycleValue, LocalDateTime firstPlanDateStart) {
		LocalDateTime dateTime = null;
		switch (unit) {
		case "hour":
			dateTime = firstPlanDateStart.plusHours(cycleValue);
			break;
		case "day":
			dateTime = firstPlanDateStart.plusDays(cycleValue);
			break;
		case "week":
			dateTime = firstPlanDateStart.plusDays(cycleValue * 7);
			break;
		case "month":
			dateTime = firstPlanDateStart.plusMonths(cycleValue);
			break;
		case "quarter":
			dateTime = firstPlanDateStart.plusMonths(cycleValue * 3);
			break;
		case "year":
			dateTime = firstPlanDateStart.plusYears(cycleValue);
			break;
		default:
			throw new RuntimeException("传入数据无法转换时间！");
		}
		return dateTime;
	}

	// 将1周、1月等数据转换为具体多少小时
	public int getCycleDataToHouse(String unit,int cycleValue) {
		int totalHouse = 0;
		switch (unit) {
		case "hour":
			totalHouse = cycleValue;
			break;
		case "day":
			totalHouse = cycleValue * 24;
			break;
		case "week":
			totalHouse = cycleValue * 7 * 24;
			break;
		case "month":
			totalHouse = cycleValue * 30 * 24;
			break;
		case "quarter":
			totalHouse = cycleValue * 3 * 30 * 24;
			break;
		case "year":
			totalHouse = cycleValue * 12 * 30 * 24;
			break;
		default:
			throw new RuntimeException("传入数据无法转换时间！");
		}
		return totalHouse;
	}

	
}
